package com.xckj.cycling.activity;

import android.Manifest;
import android.content.Intent;
import android.os.Build;
import android.util.Log;
import android.view.View;
import androidx.annotation.RequiresApi;
import androidx.recyclerview.widget.LinearLayoutManager;
import com.inuker.bluetooth.library.search.SearchRequest;
import com.inuker.bluetooth.library.search.SearchResult;
import com.inuker.bluetooth.library.search.response.SearchResponse;
import com.tbruyelle.rxpermissions3.Permission;
import com.tbruyelle.rxpermissions3.RxPermissions;
import com.xckj.cycling.R;
import com.xckj.cycling.adapter.DeviceAddedAdapter;
import com.xckj.cycling.adapter.SearchDeviceAdapter;
import com.xckj.cycling.bean.DeviceAddedResponseBean;
import com.xckj.cycling.bean.common.EventBusBean;
import com.xckj.cycling.bean.common.EventTag;
import com.xckj.cycling.bluetooth.BluetoothClientManager;
import com.xckj.cycling.databinding.ActivityAddDeviceBinding;
import com.xckj.cycling.framework.BaseActivity;
import com.xckj.cycling.iview.IBindDeviceView;
import com.xckj.cycling.iview.IDeviceAddedView;
import com.xckj.cycling.presenter.BindDevicePresenter;
import com.xckj.cycling.presenter.DeviceAddedPresenter;
import com.xckj.cycling.view.dialog.BlePairLoadingDialog;
import io.reactivex.rxjava3.annotations.NonNull;
import io.reactivex.rxjava3.core.Observer;
import io.reactivex.rxjava3.disposables.Disposable;
import org.greenrobot.eventbus.EventBus;
import org.greenrobot.eventbus.Subscribe;
import org.greenrobot.eventbus.ThreadMode;

import java.util.ArrayList;
import java.util.List;

/**
 * @Author: ChenYao
 * @Describe: 添加设备
 * @Date: 2023/3/8 23:13
 */
public class AddDeviceActivity extends BaseActivity<ActivityAddDeviceBinding>
        implements IDeviceAddedView, IBindDeviceView {
    private static final String TAG = AddDeviceActivity.class.getSimpleName();

    private DeviceAddedAdapter deviceAddedAdapter;
    private SearchDeviceAdapter searchDeviceAdapter;
    private List<SearchResult> mSearchResults;
    private BlePairLoadingDialog blePairLoadingDialog;
    private boolean fromReg;

    @Override
    protected int loadLayout() {
        return R.layout.activity_add_device;
    }

    @Override
    protected void setTitle() {
        super.setTitle();
        dataBinding.viewTitle.tvTitle.setText(getString(R.string.add_device));
    }

    @RequiresApi(api = Build.VERSION_CODES.S)
    @Override
    protected void initData() {
        fromReg = getIntent().getIntExtra("reg", -1) == 1;
        if (fromReg) {
            dataBinding.llSkip.setVisibility(View.VISIBLE);
            checkHealth();
        }
        super.initData();
        EventBus.getDefault().register(this);

        dataBinding.switchBluetooth.setChecked(BluetoothClientManager.getBluetoothClient().isBluetoothOpened());
        if (BluetoothClientManager.getBluetoothClient().isBluetoothOpened()) {
            searchDevice();
        }
        initDeviceAddedList();
        getDeviceAdded();

        // 搜索列表
        initSearchList();

        blePairLoadingDialog = new BlePairLoadingDialog(this);
        blePairLoadingDialog.create();
        blePairLoadingDialog.setOnDismissListener(dialogInterface -> {
            // close dialog
            BluetoothClientManager.getBluetoothClient().stopSearch();
        });
    }

    // 已添加列表
    private void initDeviceAddedList() {
        deviceAddedAdapter = new DeviceAddedAdapter();
        dataBinding.recDeviceAdded.setLayoutManager(new LinearLayoutManager(this));
        dataBinding.recDeviceAdded.setAdapter(deviceAddedAdapter);
        deviceAddedAdapter.setData(new ArrayList<>());
        deviceAddedAdapter.setOnItemClickListener(sn_mac -> {
            // item点击
            blePairLoadingDialog.show();
            EventBus.getDefault().post(new EventBusBean(EventTag.EventTag_conn_ble, sn_mac));
        });
    }

    // 初始化搜索列表
    private void initSearchList() {
        mSearchResults = new ArrayList<>();
        searchDeviceAdapter = new SearchDeviceAdapter();
        dataBinding.recSearchResult.setLayoutManager(new LinearLayoutManager(this));
        dataBinding.recSearchResult.setAdapter(searchDeviceAdapter);
        searchDeviceAdapter.setOnItemClickListener(searchResult -> {
            BluetoothClientManager.getBluetoothClient().stopSearch();
            String MAC = searchResult.getAddress();
            BindDevicePresenter bindDevicePresenter = new BindDevicePresenter(this);
            bindDevicePresenter.bindDevice(MAC, searchResult.getName());
        });
    }

    private void getDeviceAdded() {
        DeviceAddedPresenter deviceAddedPresenter = new DeviceAddedPresenter(this);
        deviceAddedPresenter.getDeviceAdded();
    }

    @RequiresApi(api = Build.VERSION_CODES.S)
    @Override
    protected void setListener() {
        super.setListener();
        // switch
        dataBinding.switchBluetooth.setOnCheckedChangeListener((compoundButton, b) -> {
            if (b) {
                openBluetooth();
            } else {
                closeBluetooth();
                // clear list
                mSearchResults.clear();
                searchDeviceAdapter.setData(mSearchResults);
            }
        });

        dataBinding.switchDeviceAdded.setChecked(true);
        dataBinding.switchDeviceAdded.setOnCheckedChangeListener((compoundButton, b) -> {
            if (b) {
                // 显示已添加列表
                dataBinding.recDeviceAdded.setVisibility(View.VISIBLE);
            } else {
                dataBinding.recDeviceAdded.setVisibility(View.GONE);
            }
        });

        dataBinding.llSkip.setOnClickListener(view -> finish());
    }

    @RequiresApi(api = Build.VERSION_CODES.S)
    private void openBluetooth() {
        // 判断蓝牙权限
        new RxPermissions(this).requestEachCombined(
                Manifest.permission.ACCESS_FINE_LOCATION,
                Manifest.permission.BLUETOOTH_ADMIN,
                Manifest.permission.BLUETOOTH_CONNECT
        ).subscribe(new Observer<Permission>() {
            @Override
            public void onSubscribe(@NonNull Disposable d) {

            }

            @Override
            public void onNext(@NonNull Permission permission) {
                if (permission.granted) {
                    new Thread(() -> {
                        // 打开蓝牙
                        BluetoothClientManager.getBluetoothClient().openBluetooth();
                    }).start();
                }
            }

            @Override
            public void onError(@NonNull Throwable e) {
                // 开启蓝牙权限失败
                AddDeviceActivity.this.runOnUiThread(() -> {
                    if (BluetoothClientManager.getBluetoothClient().isBluetoothOpened()) {
                        searchDevice();
                    } else {
                        showMessage(getString(R.string.bl_open_fail));
                    }
                });
            }

            @Override
            public void onComplete() {

            }
        });
    }

    @RequiresApi(api = Build.VERSION_CODES.S)
    private void closeBluetooth() {
        new RxPermissions(this).requestEachCombined(
                Manifest.permission.ACCESS_FINE_LOCATION,
                Manifest.permission.BLUETOOTH_ADMIN,
                Manifest.permission.BLUETOOTH_CONNECT
        ).subscribe(new Observer<Permission>() {
            @Override
            public void onSubscribe(@NonNull Disposable d) {

            }

            @Override
            public void onNext(@NonNull Permission permission) {
                if (permission.granted) {
                    new Thread(() -> {
                        // 关闭蓝牙
                        BluetoothClientManager.getBluetoothClient().closeBluetooth();
                    }).start();
                }
            }

            @Override
            public void onError(@NonNull Throwable e) {

            }

            @Override
            public void onComplete() {

            }
        });
    }

    /**
     * 搜寻设备
     */
    @RequiresApi(api = Build.VERSION_CODES.S)
    private void searchDevice() {
        new RxPermissions(this).requestEachCombined(
                        Manifest.permission.ACCESS_FINE_LOCATION,
                        Manifest.permission.BLUETOOTH_ADMIN,
                        Manifest.permission.BLUETOOTH_CONNECT,
                        Manifest.permission.BLUETOOTH_SCAN)
                .subscribe(new Observer<Permission>() {
                    @Override
                    public void onSubscribe(@NonNull Disposable d) {

                    }

                    @Override
                    public void onNext(@NonNull Permission permission) {
                        if (permission.granted) {
                            SearchRequest searchRequest = new SearchRequest.Builder().searchBluetoothLeDevice(5000, 2).build();
                            BluetoothClientManager.getBluetoothClient().search(searchRequest, new SearchResponse() {
                                @Override
                                public void onSearchStarted() {
                                    Log.d(TAG, "searchDevice-onSearchStarted");
                                }

                                @Override
                                public void onDeviceFounded(SearchResult device) {
                                    Log.d(TAG, "searchDevice-onDeviceFounded");
                                    if (!mSearchResults.contains(device)) {
                                        mSearchResults.add(device);
                                        searchDeviceAdapter.setData(mSearchResults);
                                    }
                                }

                                @Override
                                public void onSearchStopped() {
                                    Log.d(TAG, "searchDevice-onSearchStopped");
                                }

                                @Override
                                public void onSearchCanceled() {
                                    Log.d(TAG, "searchDevice-onSearchCanceled");
                                }
                            });
                        }
                    }

                    @Override
                    public void onError(@NonNull Throwable e) {

                    }

                    @Override
                    public void onComplete() {

                    }
                });
    }

    @Override
    public void onClick(View view) {

    }

    @Override
    public void success(List<DeviceAddedResponseBean.ListBean> deviceAdded) {
        deviceAddedAdapter.setData(deviceAdded);
    }

    @Override
    public void failure(String message) {
        showMessage(message);
    }

    @Override
    protected void onPause() {
        super.onPause();
        BluetoothClientManager.getBluetoothClient().stopSearch();
    }

    @Override
    public void bind_device_success(String macaddress) {
        showMessage("bind success");
        getDeviceAdded();
        blePairLoadingDialog.show();
        EventBus.getDefault().post(new EventBusBean(EventTag.EventTag_conn_ble, macaddress));
    }

    @Override
    public void bind_device_failure(String message) {
        showMessage(message);
    }

    @RequiresApi(api = Build.VERSION_CODES.S)
    @Subscribe(threadMode = ThreadMode.MAIN)
    public void messageEventBus(EventBusBean eventBusBean) {
        switch (eventBusBean.getTag()) {
            case EventTag_service_ble_conn_success:
                blePairLoadingDialog.dismiss();
                showMessage(getString(R.string.bl_connect_success));
                MainActivity.toMain(AddDeviceActivity.this, 0);
                break;
            case EventTag_service_ble_conn_fail:
                blePairLoadingDialog.dismiss();
                showMessage(getString(R.string.bl_connect_fail));
                break;
            case EventTag_ble_turn_on:
                searchDevice();
                break;
            case EventTag_ble_turn_off:
                // 从外部关闭的蓝牙开关
                dataBinding.switchBluetooth.setChecked(false);
                break;
        }
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        EventBus.getDefault().unregister(this);
    }

    @Override
    public void finish() {
        if (fromReg) {
            startActivity(new Intent(this, MainActivity.class).putExtra("reg", 1));
        }
        super.finish();
    }

}
